import cv2
import numpy as np
from pynput import mouse, keyboard
from pynput.mouse import Listener as MouseListener
from pynput.keyboard import Listener as KeyboardListener
import threading
import time
import win32gui
import win32con

# 用于存储操作信息和坐标
operation_info = []
info_lock = threading.Lock()  # 锁，确保线程安全

# 创建一个 OpenCV 窗口
screen_width = 800  # 屏幕宽度
screen_height = 200  # 屏幕高度
window_name = "Operation record"

# 创建一个黑色背景图像
background = np.zeros((screen_height, screen_width, 3), dtype=np.uint8)

# 显示的文本框配置
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.6
font_color = (0, 0, 0)  # 黑色字体
thickness = 2
line_type = cv2.LINE_AA

# 半透明矩形背景颜色
rect_color = (255, 255, 255)  # 白色背景
rect_alpha = 0.4  # 透明度（0 到 1 之间的值，0 完全透明，1 完全不透明）

# 用于显示信息的文本框
def show_text():
    while True:
        # 复制背景图像
        display_img = background.copy()

        # 显示操作信息
        y_offset = 20
        with info_lock:  # 确保读取时的线程安全
            for info in operation_info[-3:]:  # 只显示最后三条操作记录
                text = f"{info[0]} - Mouse Position: {info[1]}"

                # 计算文本框大小
                (text_width, text_height), baseline = cv2.getTextSize(text, font, font_scale, thickness)

                # 计算文本框的左上角和右下角
                rect_top_left = (10, y_offset - 10)
                rect_bottom_right = (10 + text_width + 20, y_offset + text_height + 10)

                # 在文本框区域绘制一个半透明矩形
                overlay = display_img.copy()
                cv2.rectangle(overlay, rect_top_left, rect_bottom_right, rect_color, -1)  # 绘制填充矩形
                cv2.addWeighted(overlay, rect_alpha, display_img, 1 - rect_alpha, 0, display_img)  # 叠加透明度

                # 在矩形框内绘制文本
                cv2.putText(display_img, text, (10 + 10, y_offset + text_height), font, font_scale, font_color, thickness, line_type)

                # 更新 y_offset
                y_offset += text_height + 30

        # 显示文本框
        cv2.imshow(window_name, display_img)

        # 获取窗口句柄并将其置顶
        hwnd = win32gui.FindWindow(None, window_name)  # 获取窗口句柄
        if hwnd:
            win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

        # 每次更新后暂停 0.1 秒
        time.sleep(0.1)

        # 按下 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cv2.destroyAllWindows()

# 监听鼠标事件
def on_move(x, y):
    with info_lock:  # 保证鼠标事件记录线程安全
        operation_info.append(('Mouse moved', (x, y)))

def on_click(x, y, button, pressed):
    action = 'Pressed' if pressed else 'Released'
    with info_lock:  # 保证鼠标事件记录线程安全
        operation_info.append((f'Mouse {action} {button}', (x, y)))

# 监听键盘事件
def on_press(key):
    try:
        with info_lock:  # 保证键盘事件记录线程安全
            operation_info.append((f'Key pressed: {key.char}', None))
    except AttributeError:
        with info_lock:  # 保证键盘事件记录线程安全
            operation_info.append((f'Key pressed: {key}', None))

def on_release(key):
    if key == keyboard.Key.esc:
        # 停止监听
        return False

# 启动鼠标监听线程
mouse_listener = MouseListener(on_move=on_move, on_click=on_click)
mouse_thread = threading.Thread(target=mouse_listener.start)
mouse_thread.start()

# 启动键盘监听线程
keyboard_listener = KeyboardListener(on_press=on_press, on_release=on_release)
keyboard_thread = threading.Thread(target=keyboard_listener.start)
keyboard_thread.start()

# 启动显示操作信息的线程
display_thread = threading.Thread(target=show_text)
display_thread.start()
